package com.ext.aic.fragment;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.EditText;

import androidx.recyclerview.widget.LinearLayoutManager;

import com.ext.aic.AICManager;
import com.ext.aic.R;
import com.ext.aic.adapter.HostingTimeAdapter;
import com.ext.aic.apis.agent.InsertUpdateAIRequest;
import com.ext.aic.apis.agent.QueryAgentRequest;
import com.ext.aic.beans.AISeparateItem;
import com.ext.aic.beans.AISeparateItem_;
import com.ext.aic.beans.HostingTimeItem;
import com.ext.aic.beans.HostingTimeItem_;
import com.ext.aic.beans.MenuItem;
import com.ext.aic.beans.params.InsertUpdateAIParams;
import com.ext.aic.beans.response.InsertUpdateAIResponse;
import com.ext.aic.beans.response.QueryAgentResponse;
import com.ext.aic.components.MenuBottomPopup;
import com.ext.aic.constants.EBusConstants;
import com.ext.aic.databinding.AiSeparateLayoutBinding;
import com.ext.aic.ui.AITestActivity;
import com.ext.aic.utils.BoxUtils;
import com.ext.aic.utils.LoadingUtils;
import com.ext.aic.utils.RedirectUtils;
import com.ext.aic.utils.ToastyUtils;
import com.ext.aic.utils.UserUtils;
import com.ext.aic.utils.XPopupUtils;
import com.ext.aic.utils.device.DeviceUtils;
import com.eyinfo.android_pure_utils.ebus.EBus;
import com.eyinfo.android_pure_utils.ebus.SubscribeEBus;
import com.eyinfo.android_pure_utils.events.Action1;
import com.eyinfo.android_pure_utils.snow.Butterfly;
import com.eyinfo.android_pure_utils.utils.ConvertUtils;
import com.eyinfo.android_pure_utils.utils.ModelConvert;
import com.mobsandgeeks.saripaar.annotation.Length;
import com.mobsandgeeks.saripaar.annotation.NotEmpty;
import com.mobsandgeeks.saripaar.annotation.Pattern;

import java.util.ArrayList;
import java.util.List;

import io.objectbox.query.QueryBuilder;

public class AISeparateFragment extends BaseFormFragment {

    private AiSeparateLayoutBinding binding;

    private boolean submitFlag;
    private boolean showLoading = false;

    private HostingTimeAdapter hostingTimeAdapter;

    @NotEmpty(message = "请输入姓名")
    @Length(max = 10, message = "姓名长度不能超过10个字符")
    private EditText nameEt;

    @Pattern(regex = "^([1-9]|[1-9][0-9]|1[0-1][0-9]|120)$", message = "年龄只能输入1~120岁之间")
    private EditText ageEt;

    @Length(max = 20, message = "籍贯长度不能超过20个字符")
    private EditText nativePlaceEt;

    @Length(max = 10, message = "职业长度不能超过10个字符")
    private EditText occupationEt;

    @Length(max = 10, message = "别名长度不能超过10个字符")
    private EditText aliasEt;

    @Length(max = 100, message = "背景内容长度不能超过100个字符")
    private EditText otherBackgroundEt;

    @Length(max = 100, message = "目标内容长度不能超过100个字符")
    private EditText targetEt;

    @Length(max = 500, message = "场景案例长度不能超过500个字符")
    private EditText exampleEt;

    @Length(max = 100, message = "回复注意事项长度不能超过100个字符")
    private EditText notesEt;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.ai_separate_layout, container, false);
        binding = AiSeparateLayoutBinding.bind(view);
        bindView();
        return binding.getRoot();
    }

    private void bindView() {
        nameEt = binding.nameEt;
        ageEt = binding.ageEt;
        nativePlaceEt = binding.nativePlaceEt;
        occupationEt = binding.occupationEt;
        aliasEt = binding.aliasEt;
        otherBackgroundEt = binding.otherBackgroundEt;
        targetEt = binding.targetEt;
        exampleEt = binding.exampleEt;
        notesEt = binding.notesEt;

        binding.topView.testBtn.setOnClickListener(this::onAITestClick);
        binding.nameEt.setOnFocusChangeListener(this::onNameFocusChange);
        binding.ageEt.setOnFocusChangeListener(this::onAgeFocusChange);
        binding.submitBtn.setOnClickListener(this::onSubmitClick);
        binding.speakingStyleRl.setOnClickListener(this::onSpeakingStyleClick);
        binding.topView.aiSeparateSwitch.setOnCheckedChangeListener(this::onAiSeparateSwitchClick);

        binding.hostingTimeRv.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
        hostingTimeAdapter = new HostingTimeAdapter();
        binding.hostingTimeRv.setAdapter(hostingTimeAdapter);
    }

    public void onAiSeparateSwitchClick(CompoundButton buttonView, boolean isChecked) {
        if (!enableConfigAISeparate()) {
            ToastyUtils.getInstance().show(getString(R.string.ai_separate_enable_hint));
            binding.topView.aiSeparateSwitch.setChecked(false);
            return;
        }
        if (!submitFlag) {
            submitFlag = true;
            showLoading = false;
            validatorHandler.validator.validate();
        }
        if (BoxUtils.getInstance().isEnableAISeparate(getContext())) {
            binding.topView.aiSeparateSwitch.setChecked(isChecked);
            binding.topView.testBtn.setEnabled(true);
            checkConfigButtonStatus();
        } else {
            if (isChecked) {
                BoxUtils.getInstance().enableAutoReplyFeature(true);
            } else {
                binding.topView.aiSeparateSwitch.setChecked(false);
                binding.topView.testBtn.setEnabled(false);
                checkConfigButtonStatus();
            }
        }
    }

    public void onAITestClick(View view) {
        if (enableConfigAISeparate()) {
            RedirectUtils.getInstance().startActivity(getContext(), AITestActivity.class);
            showLoading = false;
            validatorHandler.validator.validate();
        }
    }

    public void onNameFocusChange(View view, boolean hasFocus) {
        submitFlag = false;
        validatorHandler.validator.validate();
        checkConfigButtonStatus();
        binding.topView.testBtn.setEnabled(enableConfigAISeparate());
    }

    public void onAgeFocusChange(View view, boolean hasFocus) {
        submitFlag = false;
        validatorHandler.validator.validate();
        checkConfigButtonStatus();
        binding.topView.testBtn.setEnabled(enableConfigAISeparate());
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        EBus.getInstance().registered(this);
        LoadingUtils.showLoading(getContext(), R.string.loading);
        requestAgentData();
        bindHostingTimeData();
        checkConfigButtonStatus();
        binding.topView.testBtn.setEnabled(enableConfigAISeparate());
        LoadingUtils.hideLoading();
    }

    @SuppressLint("NotifyDataSetChanged")
    private void bindHostingTimeData() {
        List<HostingTimeItem> list = AICManager.getInstance().findList(HostingTimeItem.class, timeItem -> {
            String deviceId = DeviceUtils.getInstance().getDeviceId(getContext());
            timeItem.equal(HostingTimeItem_.deviceId, deviceId, QueryBuilder.StringOrder.CASE_INSENSITIVE);
        });
        hostingTimeAdapter.addItems(list);
        hostingTimeAdapter.notifyDataSetChanged();
    }

    private boolean enableConfigAISeparate() {
        String name = binding.nameEt.getText().toString();
        String age = binding.ageEt.getText().toString();
        String gender = "";
        int checkedRadioButtonId = binding.genderRg.getCheckedRadioButtonId();
        if (checkedRadioButtonId == R.id.male_rb) {
            gender = "1";
        } else if (checkedRadioButtonId == R.id.female_rb) {
            gender = "2";
        } else if (checkedRadioButtonId == R.id.other_rb) {
            gender = "3";
        }
        String speakingStyle = binding.speakingStyleTv.getText().toString();
        return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(age) && !TextUtils.isEmpty(gender) && !TextUtils.isEmpty(speakingStyle);
    }

    public void onSubmitClick(View view) {
        String speakingStyle = binding.speakingStyleTv.getText().toString();
        if (TextUtils.isEmpty(speakingStyle)) {
            ToastyUtils.getInstance().show(getString(R.string.speaking_style_hint));
            return;
        }
        submitFlag = true;
        showLoading = true;
        validatorHandler.validator.validate();
    }

    public void onSpeakingStyleClick(View view) {
        List<MenuItem> styleItems = buildMenuData();
        MenuBottomPopup bottomPopup = new MenuBottomPopup(getContext(), styleItems);
        bottomPopup.setItemClickCall((item) -> {
            binding.speakingStyleTv.setText(item.getName());
            checkConfigButtonStatus();
            binding.topView.testBtn.setEnabled(enableConfigAISeparate());
        });
        XPopupUtils.getInstance().showBottomDialog(getContext(), bottomPopup);
    }

    private List<MenuItem> buildMenuData() {
        List<MenuItem> items = new ArrayList<>();
        items.add(new MenuItem("专业严谨", false));
        items.add(new MenuItem("亲和友善", false));
        items.add(new MenuItem("幽默风趣", false));
        items.add(new MenuItem("沉稳冷静", false));
        return items;
    }

    @Override
    public void onValidationSucceeded() {
        if (submitFlag) {
            if (showLoading) {
                LoadingUtils.showLoading(getContext(), R.string.processing);
            }
            AISeparateItem aiSeparateItem = findAISeparateItem();
            if (aiSeparateItem == null || aiSeparateItem.getId() == null) {
                aiSeparateItem = new AISeparateItem();
                aiSeparateItem.setId(Butterfly.getInstance().nextId());
                aiSeparateItem.setDeviceId(DeviceUtils.getInstance().getDeviceId(getContext()));
            }
            bindData(aiSeparateItem);
            AICManager.getInstance().insertOrUpdate(AISeparateItem.class, aiSeparateItem);
            if (showLoading) {
                LoadingUtils.hideLoading();
                binding.topView.testBtn.setEnabled(true);
                checkConfigButtonStatus();
                ToastyUtils.getInstance().show(getString(R.string.config_complete));
            }

            InsertUpdateAIParams model = ModelConvert.toModel(aiSeparateItem, InsertUpdateAIParams.class);
            model.setUserId(UserUtils.getInstance().getUserId());
            insertUpdateAIRequest.request(getContext(), this, model);
        }
    }

    private InsertUpdateAIRequest insertUpdateAIRequest = new InsertUpdateAIRequest() {
        @Override
        protected void onInsertUpdateAISuccess(InsertUpdateAIResponse response) {
            AISeparateItem separateItem = findAISeparateItem();
            if (separateItem == null || separateItem.getId() == null) {
                separateItem = new AISeparateItem();
                separateItem.setId(Butterfly.getInstance().nextId());
                separateItem.setDeviceId(DeviceUtils.getInstance().getDeviceId(getContext()));
            }
            separateItem.setUpdateService(true);
            AICManager.getInstance().insertOrUpdate(AISeparateItem.class, separateItem);
        }
    };

    private void bindData(AISeparateItem separateItem) {
        binding.topView.aiSeparateSwitch.setChecked(BoxUtils.getInstance().isEnableAISeparate(getContext()));
        separateItem.setName(nameEt.getText().toString());
        //1-男；2-女；3-未知
        int checkedRadioButtonId = binding.genderRg.getCheckedRadioButtonId();
        if (checkedRadioButtonId == R.id.male_rb) {
            separateItem.setGender("1");
        } else if (checkedRadioButtonId == R.id.female_rb) {
            separateItem.setGender("2");
        } else if (checkedRadioButtonId == R.id.other_rb) {
            separateItem.setGender("3");
        }
        separateItem.setAge(ConvertUtils.toInt(ageEt.getText().toString()));
        separateItem.setNativePlace(nativePlaceEt.getText().toString());
        separateItem.setOccupation(occupationEt.getText().toString());
        separateItem.setAlias(aliasEt.getText().toString());
        separateItem.setSpeakingStyle(binding.speakingStyleTv.getText().toString());
        separateItem.setOtherBackground(otherBackgroundEt.getText().toString());
        separateItem.setTarget(targetEt.getText().toString());
        separateItem.setExample(exampleEt.getText().toString());
        separateItem.setNotes(notesEt.getText().toString());
    }

    private AISeparateItem findAISeparateItem() {
        return AICManager.getInstance().findOne(AISeparateItem.class, new Action1<QueryBuilder<AISeparateItem>>() {
            @Override
            public void call(QueryBuilder<AISeparateItem> builder) {
                String deviceId = DeviceUtils.getInstance().getDeviceId(getContext());
                builder.equal(AISeparateItem_.deviceId, deviceId, QueryBuilder.StringOrder.CASE_INSENSITIVE);
            }
        });
    }

    private QueryAgentRequest queryAgentRequest = new QueryAgentRequest() {
        @Override
        protected void onQueryAgentSuccess(QueryAgentResponse response) {
            AISeparateItem model = ModelConvert.toModel(response, AISeparateItem.class);
            model.setId(Butterfly.getInstance().nextId());
            model.setUpdateService(true);
            AICManager.getInstance().insertOrUpdate(AISeparateItem.class, model);

            bindAISeparateData(model);
        }
    };

    private void requestAgentData() {
        String userId = UserUtils.getInstance().getUserId();
        AISeparateItem separateItem = findAISeparateItem();
        if (separateItem != null && separateItem.getId() != null) {
            bindAISeparateData(separateItem);
            if (!separateItem.isUpdateService()) {
                InsertUpdateAIParams model = ModelConvert.toModel(separateItem, InsertUpdateAIParams.class);
                model.setUserId(userId);
                insertUpdateAIRequest.request(getContext(), this, model);
            }
            return;
        }
        queryAgentRequest.request(getContext(), this, userId, true);
    }

    private void bindAISeparateData(AISeparateItem separateItem) {
        binding.nameEt.setText(separateItem.getName());
        String gender = TextUtils.isEmpty(separateItem.getGender()) ? "1" : separateItem.getGender();
        switch (gender) {
            case "1":
                binding.maleRb.setChecked(true);
                break;
            case "2":
                binding.femaleRb.setChecked(true);
                break;
            case "3":
                binding.otherRb.setChecked(true);
                break;
        }
        binding.ageEt.setText(String.valueOf(separateItem.getAge()));
        binding.nativePlaceEt.setText(separateItem.getNativePlace());
        binding.occupationEt.setText(separateItem.getOccupation());
        binding.aliasEt.setText(separateItem.getAlias());
        binding.speakingStyleTv.setText(separateItem.getSpeakingStyle());
        binding.otherBackgroundEt.setText(separateItem.getOtherBackground());
        binding.targetEt.setText(separateItem.getTarget());
        binding.exampleEt.setText(separateItem.getExample());
        binding.notesEt.setText(separateItem.getNotes());
    }

    @SuppressLint("NotifyDataSetChanged")
    @SubscribeEBus(receiveKey = {EBusConstants.selectHostingTime})
    public void onSelectHostingTime(int startHour, int startMinute, int endHour, int endMinute) {
        HostingTimeItem timeItem = saveHostingTime(startHour, startMinute, endHour, endMinute);
        hostingTimeAdapter.addItem(timeItem);
        hostingTimeAdapter.notifyDataSetChanged();
        binding.sv.fullScroll(View.FOCUS_DOWN);
        LoadingUtils.hideLoading();
    }

    private HostingTimeItem saveHostingTime(int startHour, int startMinute, int endHour, int endMinute) {
        String deviceId = DeviceUtils.getInstance().getDeviceId(getContext());
        HostingTimeItem timeItem = AICManager.getInstance().findOne(HostingTimeItem.class, new Action1<QueryBuilder<HostingTimeItem>>() {
            @Override
            public void call(QueryBuilder<HostingTimeItem> builder) {
                builder.equal(HostingTimeItem_.deviceId, deviceId, QueryBuilder.StringOrder.CASE_INSENSITIVE);
                builder.equal(HostingTimeItem_.startHour, startHour);
                builder.equal(HostingTimeItem_.startMinute, startMinute);
                builder.equal(HostingTimeItem_.endHour, endHour);
                builder.equal(HostingTimeItem_.endMinute, endMinute);
            }
        });
        if (timeItem == null || timeItem.getId() == null) {
            timeItem = new HostingTimeItem();
            timeItem.setId(Butterfly.getInstance().nextId());
            timeItem.setDeviceId(DeviceUtils.getInstance().getDeviceId(getContext()));
        }
        timeItem.setStartHour(startHour);
        timeItem.setStartMinute(startMinute);
        timeItem.setEndHour(endHour);
        timeItem.setEndMinute(endMinute);
        AICManager.getInstance().insertOrUpdate(HostingTimeItem.class, timeItem);
        return timeItem;
    }

    @SubscribeEBus(receiveKey = EBusConstants.detectionAISeparateEnable)
    public void onDetectionAISeparateEnableEvent() {
        boolean enableAISeparate = BoxUtils.getInstance().isEnableAISeparate(getContext());
        binding.topView.aiSeparateSwitch.setChecked(enableAISeparate);
        binding.topView.testBtn.setEnabled(enableAISeparate);
        checkConfigButtonStatus();
    }

    private void checkConfigButtonStatus() {
        String name = binding.nameEt.getText().toString();
        String age = binding.ageEt.getText().toString();
        String nativePlace = binding.nativePlaceEt.getText().toString();
        String occupation = binding.occupationEt.getText().toString();
        String alias = binding.aliasEt.getText().toString();
        String speakingStyle = binding.speakingStyleTv.getText().toString();
        String target = binding.targetEt.getText().toString();
        String example = binding.exampleEt.getText().toString();
        binding.submitBtn.setEnabled(!TextUtils.isEmpty(name) &&
                !TextUtils.isEmpty(age) &&
                !TextUtils.isEmpty(nativePlace) &&
                !TextUtils.isEmpty(occupation) &&
                !TextUtils.isEmpty(alias) &&
                !TextUtils.isEmpty(speakingStyle) &&
                !TextUtils.isEmpty(target) &&
                !TextUtils.isEmpty(example));
    }
}
